在前面的兩篇提到了 when、only 及 except 來設定工作的執行條件,在這一篇裡,將要提到 rules 這個在 GitLab 12.3 之後提供的條件設定功能。這是一個可以說結合了 when、only 及 except 三者功能的參數,那麼它可以做些什麼呢?
rules 可以作些什麼?在 rules 參數裡,可以搭配 when、allow_failure、if、changes 及 exists 等等的參數,舉手冊上的例子來說:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: delayed
start_in: '3 hours'
allow_failure: true
這個範例提供了「如果 GIT commit 的分支為 master 時,那就在 3 小時之後執行這個工作,且允許執行失敗」。可以發現,寫 rules 的條件判斷,相對使用 when、only 及 except 多了一些「邏輯感」,因此,我個人在使用上如遇到比較複雜的條件時,我會傾向使用 rules 來完成。但必須注意,「不能」把 rules 與 only 及 except同時使用,且就算透過 CI Lint 檢測語法,可能也不會顯示錯誤。
rules 的參數目前 rules 主要提供了三個參數:
if:透過 if 這個參數可以設定或排除某些條件,其功能與 only:variables 提供的相似。changes:當 GIT Commit 的檔案內容包含設定的檔案變更時執行,其效果與 only:changes 的功能相似。exist:當 GIT Commit 裡的檔案存在某些檔案時執行。在同一個 rules 裡頭,條件之間是以「且 AND」的型態呈現,但參數裡頭則是以「或 OR」的型態描述,舉底下的例子來說:
build:docker:
script:
- echo 'build docker image'
rules:
- if: '$VAR == "string value"'
changes:
- Dockerfile
- docker/scripts/*
when: manual
上面的例子成立的條件是:
$VAR 的內容為 “string value”Dockerfile 「或」docker/scripts/* 資料夾底下的檔案。另外 rules:if 自 GitLab 13.3 開始,條件還可以搭配括弧(Parentheses)來描述,如官方手冊的範例,透過括弧可以搭配出更「多元」的條件:
job1:
script:
- echo This rule uses parentheses.
rules:
if: ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
rules 下的 allow_failure另外,如果在 job 與 rules 中都使用了 allow_failure,則 rules 階層的 allow_failure 可以覆寫掉 job 階層的。如底下的範例,當 if 條件成立時,則 allow_failure 為 true。
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
when: manual
allow_failure: true
rules 的條件流程GitLab CI 的 rules 可以同時設定多個條件式,其聯合在一起的效果就如邏輯判斷中的「if...elseif...elseif...」類似,因此,使用上也必須要注意,當其中一個「條件」成立了,則該工作以這個條件設定的內容為主。
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
以上面的這個例子來說,總共有兩個條件式,其一是「當流水線的啟動來自 Merge 請求,且手動觸發時,則允許這個工作失敗」,其二「當流水線的啟動來自排程」,這代表著,當成立條件為第一項時「允許工作失敗」,當成立條件為第二項時,則「不允許」工作失敗(allow_failure: false 為預設值),當兩個條件都不成立時,則這個工作不執行。
那麼,如果要設定反向邏輯呢?如手冊上提出的範例:
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- when: on_success
條件是如下:
在 rules 的使用裡,我們可以透過更豐富多元的條件來設定工作該不該作,但也必須要特別注意這些條件是否能真正描述到想要達成的條件,另外也要特別注意條件成立時內額外設定的參數,是否是預期的。
接下來要繼續談工作與工作之間的互動。我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。